package com.kis.core.util;

import ch.qos.logback.classic.sift.SiftAction;
import com.kis.core.util.model.Hessian;
import com.kis.core.util.model.HessianBean;
import com.kis.core.util.model.ServerInfo;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.RandomRule;
import com.sun.corba.se.impl.activation.ServerTool;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by wongloong on 16-5-11.
 */
public class HessianBalance {
    private static Map<String, Object> hessians = new ConcurrentHashMap<String, Object>();
    private static Map<String, List<ServerInfo>> serverMap = new ConcurrentHashMap<String, List<ServerInfo>>();
    private static Map<String, Hessian> hessianMap = new ConcurrentHashMap<String, Hessian>();

    public static Object CheckBestHessianProxy(String accessPath) {
        Object o = null;
        if (hessianMap.isEmpty()) {
            hessianMap = Timer.getHessianMap();
        }
        DynamicServerListLoadBalancer lb = new DynamicServerListLoadBalancer();
        lb.setServersList(getAllHessianBeanByAccessPath(accessPath));
        RandomRule randomRule = new RandomRule();
        ServerInfo serverInfo = (ServerInfo) randomRule.choose(lb, null);
        o = serverInfo.getHessian();
//        System.out.println("本地调用Key" + accessPath + " 本次调用ip:" + serverInfo.getHost());
        return o;
    }

    public static List<ServerInfo> getAllHessianBeanByAccessPath(String accessPath) {
        List<ServerInfo> serverInfos = new ArrayList<>();
        if (!hessianMap.isEmpty()) {
            for (Map.Entry<String, Hessian> entry : hessianMap.entrySet()) {
                for (HessianBean h : entry.getValue().getHessianBeanList()) {
                    if (h.getAccessPath().equalsIgnoreCase(accessPath)) {
                        serverInfos.add(new ServerInfo(h.getUri(), h.getPort(), h.getHessian()));
                    }
                }
            }
        }
        return serverInfos;
    }

    public static void assemableHessianProxy() {
        if (!hessians.isEmpty()) {
            for (Map.Entry<String, Object> entry : hessians.entrySet()) {
                String value = entry.getValue().toString();
                String key = StringTools.getKey(value);
                String url = StringTools.getUrl(value);
                if (!StringUtils.isEmpty(key)) {
                    if (serverMap.containsKey(key)) {
                        List<ServerInfo> oldListServerInfo = serverMap.get(key);
                        oldListServerInfo.add(new ServerInfo(StringTools.getHost(url), StringTools.getPort(url), entry.getValue()));
                    } else {
                        List<ServerInfo> mapList = new ArrayList<ServerInfo>();
                        mapList.add(new ServerInfo(StringTools.getHost(url), StringTools.getPort(url), entry.getValue()));
                        serverMap.put(key, mapList);
                    }
                }
            }
        }
    }

    public static void assemableHessianProxy(Map<String, Hessian> hm) {
        setHessianMap(hm);
    }

    public static void assemableHessianProxy(Map<String, Object> currHessian, String problemKey) {
        List<ServerInfo> serverInfos = new ArrayList();//serverMap.get(problemKey);
        if (null != currHessian) {
            for (Map.Entry<String, Object> entry : currHessian.entrySet()) {
                String value = entry.getValue().toString();
                String key = StringTools.getKey(value);
                String url = StringTools.getUrl(value);
                ServerInfo serverInfo = new ServerInfo(StringTools.getHost(url), StringTools.getPort(url), entry.getValue());
                serverInfos.add(serverInfo);
            }
        }
        serverMap.remove(problemKey);
        serverMap.put(problemKey, serverInfos);
    }

    public static Map<String, Object> getHessians() {
        return hessians;
    }

    public static void setHessians(Map<String, Object> hessians) {
        HessianBalance.hessians = hessians;
        assemableHessianProxy();
    }

    public static Map<String, Hessian> getHessianMap() {
        return hessianMap;
    }

    public static void setHessianMap(Map<String, Hessian> hessianMap) {
        HessianBalance.hessianMap = hessianMap;
    }

    public static void setHessiansWithKey(Integer port, String accessPath) {
        String serverName = "";
        for (Map.Entry<String, Hessian> hessianEntry : hessianMap.entrySet()) {
            List<HessianBean> hbs = hessianEntry.getValue().getHessianBeanList();
            Iterator<HessianBean> iterator = hbs.iterator();
            while (iterator.hasNext()) {
                HessianBean hb = iterator.next();
                if (hb.getAccessPath().equalsIgnoreCase(accessPath)) {
                    serverName = hb.getServerName();
                    break;
                }
            }
        }
        Hessian hessian= hessianMap.get(serverName);
        Iterator<HessianBean> hessianBeanIterator = hessian.getHessianBeanList().iterator();
        while (hessianBeanIterator.hasNext()) {
            HessianBean hb = hessianBeanIterator.next();
            if (hb.getPort().equals(port)) {
                hessianBeanIterator.remove();
            }
        }
    }
}
